import { MciButton, MciNotification, MciSubCard, MciTable, MciTableColumn } from '@/components/base';
import { useGraph } from '@/hooks/useGraph';
import { IResultOfNodeItem, useNodeResults } from '@/store/node-results';
import { getAllVariables } from '@/utils/graph';
import { ElDrawer } from 'element-plus';
import './index.scss';

export const NodeLogger = defineComponent({
  name: 'NodeLogger',
  props: {
    nodeId: {
      type: String,
      default: ''
    }
  },
  setup(props) {
    const resultsStore = useNodeResults();
    const { graph } = useGraph();
    const visible = ref(false);
    const focusResult = ref({} as IResultOfNodeItem);

    const results = computed(() => {
      if (!props.nodeId) return [];
      return resultsStore.resultsOfList?.filter((item) => item.nodeId === props.nodeId) || [];
    });

    const variables = getAllVariables(graph.value!, 'private') || [];
    const nodeVariables = getAllVariables(graph.value!, 'node') || [];
    variables.push(...nodeVariables);
    const variableOfLabelMap = variables.reduce((prev: Record<string, any>, curr) => {
      prev[curr.varName!] = curr.varLabel || curr.varName;
      return prev;
    }, {} as Record<string, string>);

    // 提取入参
    const getParamsList = (params: Record<string, any>, variableLabelMap: Record<string, string>) => {
      const res: { key: string; label: string; value: any }[] = [];
      if (params) {
        const paramsList = params['_params'];
        if (paramsList) {
          let firstParam: any = null;
          let map: any = {};
          paramsList.forEach((element: any) => {
            if (element) {
              if (!firstParam) firstParam = element;
              const keys = Object.keys(element);
              if (keys) {
                keys.forEach((key) => {
                  if (map[key]) {
                    map[key].push(element[key]);
                  } else {
                    map[key] = [element[key]];
                  }
                });
              }
            }
          });
          // 合并参数
          for (const key in firstParam) {
            if (firstParam.hasOwnProperty(key) && key.indexOf('_') !== 0) {
              const row: any = {
                key,
                label: variableLabelMap[key] || key
              };
              const values = map[key];
              if (values && values.length) {
                for (let index = 0; index < values.length; index++) {
                  const element = values[index];
                  const colIndex = `${index + 1}`;
                  row[colIndex] = element;
                }
              }
              res.push(row);
            }
          }
        } else {
          for (const key in params) {
            if (params.hasOwnProperty(key) && key.indexOf('_') !== 0) {
              const element = params[key];
              res.push({
                key,
                label: variableLabelMap[key] || key,
                value: element
              });
            }
          }
        }
      }

      // for (const key in params) {
      //   if (params.hasOwnProperty(key) && key.indexOf('_') !== 0) {
      //     const element = params[key];
      //     res.push({
      //       key,
      //       label: variableLabelMap[key] || key,
      //       value: element
      //     });
      //   }
      // }
      return res;
    };

    const copyInputParams = (data: any) => {
      if (navigator.clipboard) {
        const params: Record<string, any> = Object.assign({}, data || {});
        for (const key in params) {
          if (params.hasOwnProperty(key) && key.indexOf('_') === 0) {
            delete params[key];
          }
        }
        navigator.clipboard.writeText(JSON.stringify(params, null, 2)).then(() => {
          MciNotification.success('复制成功');
        });
      }
    };

    const copyResParams = (data: any) => {
      if (navigator.clipboard) {
        navigator.clipboard.writeText(JSON.stringify(data || {}, null, 2)).then(() => {
          MciNotification.success('复制成功');
        });
      }
    };

    const cols = computed(() => {
      return (
        results.value[0]?.result[0]?.results?.map((_, index) => {
          return 'col_' + index;
        }) || []
      );
    });

    const getDetailResponseList = (resultItem: Required<IResultOfNodeItem['result']>[number]) => {
      if (!resultItem) return [];
      const list = resultItem.variables?.map((variable) => {
        const info: Record<string, any> = {
          label: variable.varLabel
        };
        resultItem.results?.map((result: any, index) => {
          info['col_' + index] = result[variable.varName!];
        });

        return info;
      });
      return list;
    };

    return () => {
      if (!results.value.length) return null;
      return (
        <>
          <div
            onClick={(e) => e.stopPropagation()}
            class="node-logger flex flex-col gap-8 absolute top-48 left-[50%] -translate-x-[50%] w-200 px-12 py-8 bg-white rounded-8">
            {results.value.map((item) => {
              return (
                <div class="result-item">
                  <>
                    <div>
                      <label class="text-label-14">执行状态: </label>
                      {item.hasError ? (
                        <span class="text-value-14 !text-red">错误</span>
                      ) : (
                        <span class="text-value-14 !text-green-600">成功</span>
                      )}
                    </div>
                    <div>
                      <label class="text-label-14">执行耗时: </label>
                      <strong class="text-value-14_bold">{item.spendTimes} ms</strong>
                    </div>
                    <div class="input-params">
                      <label class="text-label-14">执行次数: </label>
                      <strong class="text-value-14_bold">{item.result?.length || 0}</strong>
                    </div>
                  </>

                  {!!item.result?.length || item.errorMsg ? (
                    <div class="output mt-4 text-center">
                      <a
                        onClick={() => {
                          focusResult.value = item;
                          visible.value = true;
                        }}
                        href="javascript:;"
                        class="text-label-14 !text-blue-500 cursor-pointer underline">
                        查看详细结果
                      </a>
                    </div>
                  ) : null}
                </div>
              );
            })}
          </div>

          <ElDrawer
            destroyOnClose
            size={1000}
            direction="rtl"
            onClose={() => {
              focusResult.value = {} as IResultOfNodeItem;
            }}
            appendToBody
            v-model={visible.value}>
            {{
              header() {
                return <div class="text-value-16_bold ">执行结果详情</div>;
              },
              default() {
                return (
                  <div class="result-detail py-12 flex flex-col gap-20">
                    {Boolean(focusResult.value.hasError) && (
                      <div class="text-value-14 pb-12 px-16">
                        <span class="!text-gray-600 text-value-16_bold">失败原因：</span>
                        <span class="text-value-14 !text-red">{focusResult.value.errorMsg || '失败'}</span>
                      </div>
                    )}
                    {focusResult.value.result?.map((result, resultIndex) => {
                      const resList = getDetailResponseList(result);
                      const reqList = getParamsList(result.inputParams || {}, variableOfLabelMap);
                      return (
                        <MciSubCard title={'执行轮次：' + (resultIndex + 1)}>
                          <div class="px-16">
                            <div class="text-value-14 pb-12">
                              <span class="!text-gray-600 text-value-16_bold">执行结果：</span>
                              <span class="text-value-16 !text-green-500">成功</span>
                            </div>
                            {!!reqList?.length && (
                              <>
                                <div class="flex justify-between">
                                  <span class="!text-gray-600 text-value-16_bold">节点入参</span>
                                  <MciButton onClick={() => copyInputParams(result.inputParams)} type="info">
                                    复制为JSON
                                  </MciButton>
                                </div>
                                <div class="flex items-center justify-end gap-12"></div>
                                <MciTable maxHeight={300} data={reqList}>
                                  <MciTableColumn label="参数中文名" prop="label" minWidth={100} />
                                  <MciTableColumn label="参数名" prop="key" minWidth={100} />
                                  {result.inputParams &&
                                    result.inputParams['_params'] &&
                                    result.inputParams['_params'].map((item, index) => {
                                      return (
                                        <MciTableColumn label="" prop={`${index + 1}`} minWidth={100}>
                                          {{
                                            header() {
                                              return <>{index === 0 ? <span>参数值</span> : <span></span>}</>;
                                            }
                                          }}
                                        </MciTableColumn>
                                      );
                                    })}
                                  {(!result.inputParams || !result.inputParams['_params']) && (
                                    <MciTableColumn label="参数值" prop="value" minWidth={100} />
                                  )}
                                </MciTable>
                              </>
                            )}

                            {!!resList?.length && (
                              <>
                                <div class="flex justify-between mt-20">
                                  <span class="!text-gray-600 text-value-16_bold">节点返回的结果</span>
                                  <MciButton onClick={() => copyResParams(result?.results)} type="info">
                                    复制为JSON
                                  </MciButton>
                                </div>
                                <MciTable maxHeight={400} data={resList}>
                                  <MciTableColumn label="字段描述" prop="label" />
                                  {cols.value.map((col) => {
                                    return <MciTableColumn label="" prop={col} />;
                                  })}
                                </MciTable>
                              </>
                            )}
                          </div>
                        </MciSubCard>
                      );
                    })}
                  </div>
                );
              }
            }}
          </ElDrawer>
        </>
      );
    };
  }
});
